package com.mibox.common.utils;

import androidx.annotation.NonNull;

import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.StringUtils;
import com.mibox.common.BuildConfig;
import com.mibox.common.bean.SinaStocks;
import com.mibox.common.consts.ApiUrl;
import com.tencent.mmkv.MMKV;

import java.io.IOException;
import java.util.Objects;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;

public enum HttpHelper {

    INSTANCE;

    public static final MediaType TYPE_JSON = MediaType.get("application/json; charset=utf-8");
    private OkHttpClient mClient;

    HttpHelper() {
        OkHttpClient.Builder ob = new OkHttpClient.Builder();
        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            ob.addInterceptor(logging);
        }
        mClient = ob.build();
    }

    public void init() {
    }

    public void sinaGet(String url, HttpCallback<?> cb) {
        Request req = new Request.Builder().url(url)
                .header("User-Agent", ApiUrl.SINA_APP_USER_AGENT)
                .get().build();
        enqueue(req, cb);
    }

    public void get(String url, HttpCallback<?> cb) {
        Request req = new Request.Builder().url(url).get().build();
        enqueue(req, cb);
    }

    public void postJson(String url, String json, HttpCallback<?> cb) {
        Request req = new Request.Builder().url(url)
                .post(RequestBody.create(json, TYPE_JSON)).build();
        enqueue(req, cb);
    }

    private <T> void enqueue(Request req, HttpCallback<T> cb) {
        final String cacheKey = req.method() + req.url().toString();
        String lastRes = MMKV.defaultMMKV().getString(cacheKey, "");
        if (!StringUtils.isTrimEmpty(lastRes)) {
            dealWithResponseText(lastRes, cb);
        }
        mClient.newCall(req).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                cb.onFail(e.getMessage());
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                String res = Objects.requireNonNull(response.body()).string();
                MMKV.defaultMMKV().putString(cacheKey, res);
                dealWithResponseText(res, cb);
            }
        });
    }

    private <T> void dealWithResponseText(String res, HttpCallback<T> cb) {
        Class<T> clazz = cb.entityClass;
        if (clazz.equals(String.class)) {
            cb.onSuccess((T) res);
        } else if (clazz.equals(SinaStocks.class)) {
            cb.onSuccess((T) SinaStocks.fromString(res));
        } else {
            T obj = JSON.parseObject(res, clazz);
            cb.onSuccess(obj);
        }
    }
}
